package network.protocol;
import physics.Body;
import physics.joints.Joint;
import network.byteConversions.ByteConverter;
import network.dataFormats.GroToGO;
import network.dataFormats.NetworkPackage;
import network.serializing.SerializeBody;
import network.serializing.SerializeGameObject;
import network.serializing.SerializeGraphicsObject;
import network.serializing.SerializeJoint;
import game.Game;
import game.objects.GameObject;
import graphics.objects.GraphicsObject;
// TODO Errors happen when objects are added and removed at the same frame ... this sucks ?
/**
 * Reads NetworkPackages of the type ADDx or REMx and processes them correctly. An Object mana
 * 
 * @author toni
 * 
 */
public class PackageReader {
	private Game game;
	private ObjectManager objectManager;
	public PackageReader(ClientHandler c, Game g) {
		game = g;
		this.objectManager = new ObjectManager(c, game);
	}
	public void remBodyFromPackage(NetworkPackage p) {
		int id = ByteConverter.bytesToInt(p.getData());
		if (!objectManager.remBody(id, p))
			return;
		Body b = game.engine.world.getBodyById(id);
		game.engine.world.remBody(b);
		GameObject o = game.getContainingGO(b);
		if (o != null)
			o.remNetworkBody(b);
	}
	public void addBodyFromPackage(NetworkPackage p) {
		Body b = SerializeBody.fromData(p.getData());
		if (!objectManager.addBody(b, p))
			return;
		game.engine.world.addBody(b);
	}
	public void remJointFromPackage(NetworkPackage p) {
		int id = ByteConverter.bytesToInt(p.getData());
		if (!objectManager.remJoint(id, p))
			return;
		Joint j = game.engine.world.getJointById(id);
		game.engine.world.remJoint(j);;
		GameObject o = game.getContainingGO(j);
		if (o != null)
			o.remNetworkJoint(j);
	}
	public void addJointFromPackage(NetworkPackage p) {
		Joint j = SerializeJoint.fromData(p.getData());
		if (!objectManager.addJoint(j, p))
			return;
		game.engine.world.addJoint(j);
	}
	public void remGraphicsObjectFromPackage(NetworkPackage p) {
		int id = ByteConverter.bytesToInt(p.getData());
		if (!objectManager.remGraphicsObject(id, p))
			return;
		GraphicsObject gr = game.engine.graphics.getGraphicsObjectById(id);
		game.engine.graphics.remGraphicsObject(gr);
		GameObject o = game.getContainingGO(gr);
		if (o != null)
			o.remNetworkGraphicsObject(gr);
	}
	public void addGraphicsObjectFromPackage(NetworkPackage p) {
		GraphicsObject o = SerializeGraphicsObject.fromData(p.getData());
		if (!objectManager.addGraphicsObject(o, p))
			return;
		game.engine.graphics.addGraphicsObject(o);
	}
	public void addGameObjectFromPackage(NetworkPackage p) {
		GameObject o = SerializeGameObject.fromData(p.getData());
		if (!objectManager.addGameObject(o, p))
			return;
		o.setGame(game);
		game.addGameObject(o, true);
	}
	public void remGameObjectFromPackage(NetworkPackage p) {
		int id = ByteConverter.bytesToInt(p.getData());
		if (!objectManager.remGameObject(id, p))
			return;
		game.remGameObject(game.getGOById(id), true);
	}
	public void addBodyToGameObject(NetworkPackage p) {
		int[] ids = ByteConverter.bytesToTwoInts(p.getData());
		if (!objectManager.addBodyToGameObject(ids[0], ids[1], p))
			return;
		GameObject go = game.getGOById(ids[0]);
		Body b = game.engine.world.getBodyById(ids[1]);
		go.addNetworkBody(b);
	}
	public void addJointToGameObject(NetworkPackage p) {
		int[] ids = ByteConverter.bytesToTwoInts(p.getData());
		if (!objectManager.addJointToGameObject(ids[0], ids[1], p))
			return;
		GameObject go = game.getGOById(ids[0]);
		Joint j = game.engine.world.getJointById(ids[1]);
		go.addNetworkJoint(j);
	}
	public void addGraphicsObjectToGameObject(NetworkPackage p) {
		GroToGO groToGo = ByteConverter.groToGOFromData(p.getData());
		if (!objectManager.addGraphicsObjectToGameObject(groToGo, p))
			return;
		GameObject go = game.getGOById(groToGo.goId);
		GraphicsObject gro = game.engine.graphics.getGraphicsObjectById(groToGo.grId);
		go.addNetworkGraphicsObject(gro, groToGo.sync);
	}
	public void setGame(Game g) {
		game = g;
		objectManager.setGame(g);
	}
}
